package ovm.gui.views;

import com.vaadin.data.Container;
import com.vaadin.data.Property;
import com.vaadin.ui.*;
import ovm.gui.buttons.table.EntityViewButton;
import ovm.gui.forms.AbstractEntityForm;
import ovm.gui.forms.EntityFormFactory;
import ovm.gui.selectors.AbstractEntitySelector;
import ovm.management.AbstractManager;
import ovm.management.EntityPropertyCaption;
import ovm.management.EntityTableFormManager;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import static ovm.management.AbstractManager.*;
import static ovm.application.MainApplication.*;

/**
 * Created by IntelliJ IDEA.
 * User: Jokser
 * Date: 28.05.12
 * Time: 9:10
 * To change this template use File | Settings | File Templates.
 */

public class AbstractEntityListView extends AbstractCatalogView {

    private ArrayList<AbstractEntitySelector> filters;
    private ArrayList<String> params;
    private Button filterButton;

    public class EntityViewTableButtonGenerator implements Table.ColumnGenerator {
        @Override
        public Object generateCell(Table source, Object itemId, Object columnId) {
            Integer id = (Integer) source.getItem(itemId).getItemProperty("id").getValue();
            return new EntityViewButton("Подробнее", entityClass, id, false);
        }
    }

    public class EntityTableFieldFactory implements TableFieldFactory {
        @Override
        public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
            Class propertyClass = getPropertyClass(entityClass, (String) propertyId);
            if (propertyClass.equals(String.class) || propertyClass.equals(Integer.class) || propertyClass.equals(int.class)) {
                return new TextField();
            } else if (propertyClass.equals(Date.class)) {
                DateField dateField = new DateField();
                dateField.setDateFormat("dd.MM.yyyy");
                return dateField;
            } else {
                return new AbstractEntitySelector(propertyClass);
            }
        }
    }

    @Override
    protected void setContainerProperties() {
        EntityPropertyCaption properties = EntityTableFormManager.getDefaultTableProperties(entityClass);
        entityContainer.addContainerProperty("id", Integer.class, null, true, true);

        Object[] propertiesArray = properties.getProperties();
        for (int i = 0; i < propertiesArray.length - 1; i++) {
            entityContainer.addContainerProperty(propertiesArray[i],
                    getPropertyClass(entityClass, (String) propertiesArray[i]), null, true, true);
        }
    }

    @Override
    protected void buildTable() {
        EntityPropertyCaption properties = EntityTableFormManager.getDefaultTableProperties(entityClass);

        table.addContainerProperty("details", Button.class, null);
        table.addGeneratedColumn("details", new EntityViewTableButtonGenerator());
        table.setVisibleColumns(properties.getProperties());
        table.setColumnHeaders(properties.getCaptions());
        table.setTableFieldFactory(new EntityTableFieldFactory());
    }

    @Override
    protected int addNewEntity() {
        AbstractEntityForm form = null;
        try {
            form = EntityFormFactory.createEntityForm(entityClass, entityClass.newInstance(), editable);
        } catch (InstantiationException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (IllegalAccessException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        splitPanel.setSecondComponent(form);
        return 0;
    }

    @Override
    protected void editEntity(Object tableValue) {
        if (tableValue == null) {
            navigator.showNotification("Не выбран элемент.");
        } else {
            Integer entityId = (Integer) table.getItem(tableValue).getItemProperty("id").getValue();
            Object entity = AbstractManager.getAbstractEntityById(entityClass, entityId);
            AbstractEntityForm form = null;
            try {
                form = EntityFormFactory.createEntityForm(entityClass, entity, editable);           
            } catch (Exception e) {
                e.printStackTrace();
            }
            splitPanel.setSecondComponent(form);
        }
    }

    public void setFilter (String parameter, Object value) {
        HashMap<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("par", value);
        entityContainer.filter("e."+parameter+"=:par", parameters);
    }
    
    public void setFilters(ArrayList<String> parameters, ArrayList<Object> values) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        String criteria = "";
        for (int i = 0; i < parameters.size(); i++) {
            map.put("par" + i, values.get(i));
            if (i == 0) {
                criteria += ("e."+parameters.get(i)+"=:par"+i);
            } else {
                criteria += (" and e."+parameters.get(i)+"=:par"+i);
            }
        }
        entityContainer.filter(criteria, map);
    }

    private class FilterListener implements Button.ClickListener {
        @Override
        public void buttonClick(Button.ClickEvent event) {
            ArrayList<String> parameters = new ArrayList<String>();
            ArrayList<Object> values = new ArrayList<Object>();
            for (int i = 0; i < filters.size(); i++) {
                if (filters.get(i).getValue() == null) continue;
                parameters.add(params.get(i));
                values.add(filters.get(i).getValue());
            }
            setFilters(parameters, values);
        }
    }

    private void buildFilters() {
        EntityPropertyCaption properties = EntityTableFormManager.getDefaultTableProperties(entityClass);
        filters = new ArrayList<AbstractEntitySelector>();
        params = new ArrayList<String>();

        filterLayout.setSpacing(false);

        for (Object propertyId : entityContainer.getContainerPropertyIds()) {
            if (propertyId.equals("details")) continue;
            Class propertyClass = getPropertyClass(entityClass, (String) propertyId);
            if (propertyClass.equals(int.class) || propertyClass.equals(Integer.class)
                    || propertyClass.equals(String.class) || propertyClass.equals(Date.class)) {
                //nothing
            } else {
                AbstractEntitySelector filter = new AbstractEntitySelector(propertyClass);
                for (int i = 0; i < properties.getProperties().length; i++) {
                    if (properties.getProperties()[i].equals(propertyId)) {
                        filter.setCaption(properties.getCaptions()[i]);
                        break;
                    }
                }
                filters.add(filter);
                params.add((String) propertyId);

                filterLayout.addComponent(filter);
                //filterLayout.setComponentAlignment(filter, Alignment.MIDDLE_LEFT);
            }
        }
        filterButton = new Button("Фильтр", new FilterListener());
        filterLayout.addComponent(filterButton);
        filterLayout.setComponentAlignment(filterButton, Alignment.MIDDLE_LEFT);
    }

    public void removeAllFilters() {
        filterLayout.removeAllComponents();
        filters.clear();
        params.clear();
    }

    public AbstractEntityListView(Class entityClass, Boolean editable) {
        super(entityClass, editable);
        buildFilters();
    }

}
